package com.iwunu.gateway.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iwunu.gateway.cache.RedisService;
import com.iwunu.gateway.constant.ApartmentConstant;
import com.iwunu.gateway.constant.RandomNum;
import com.iwunu.gateway.constant.ResultCodeEnum;
import com.iwunu.gateway.entity.FLockUser;
import com.iwunu.gateway.service.FlockUserService;
import com.iwunu.gateway.service.JpaService;
import com.iwunu.gateway.service.LoginService;
import com.iwunu.gateway.service.TokenService;
import com.iwunu.gateway.util.ResultUtil;
import com.iwunu.gateway.util.SmsTxSend;
import com.iwunu.gateway.util.VerifyPhoneUtil;
import com.iwunu.gateway.util.WechatDecryptDataUtil;
import com.iwunu.gateway.vo.LoginBindPhoneVo;
import com.iwunu.gateway.vo.LoginParamVo;
import com.iwunu.gateway.vo.SendSmsVo;
import com.iwunu.gateway.vo.TokenVo;
import com.iwunu.gateway.vo.UserInfoVo;
import com.iwunu.iot.common.util.DataUtil;
import com.iwunu.iot.common.util.DateUtil;
import com.iwunu.iot.common.util.Result;
import com.iwunu.iot.common.util.StringUtil;
import com.iwunu.iot.common.wechat.OpenIdUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

import javax.annotation.Resource;

/**
 * @author kinfeng
 * @date 2019/6/13 11:35 AM
 * @description
 */
@Service
public class LoginServiceImpl implements LoginService {
	private static final Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class);
    @Autowired
    private TokenService tokenService;
    @Autowired
    private FlockUserService userService;
    @Resource
    private JpaService jpaService;
    @Autowired
    public RedisService  redisService;
    
    private static final String code = "666666";
    
    public Result<Integer> sendSmsCode(String cc, String phone) {
        //校验手机号
        if(!VerifyPhoneUtil.verifyPhone(phone)){
            return  ResultUtil.generateResult(ResultCodeEnum.ERROR_PHONE.getCode(),ResultCodeEnum.ERROR_PHONE.getDesc(),null);
        }

        //限制频繁发送
        String key = ApartmentConstant.SEND_SMS_CODE_KEY+phone ;
        String smsCodeStr = redisService.get(key);
        SendSmsVo sendSmsVo = null;
        if(!StringUtil.strIsNullOrEmpty(smsCodeStr)){
            sendSmsVo = JSON.parseObject(smsCodeStr,SendSmsVo.class);
        }
        if(sendSmsVo!=null){
            sendSmsVo.setTimes(sendSmsVo.getTimes()+1);
            if(sendSmsVo.getTimes()>=ApartmentConstant.SEND_SMS_TIMES){
                return  ResultUtil.generateResult(ResultCodeEnum.FREQUENT_OPERATION.getCode(),ResultCodeEnum.FREQUENT_OPERATION.getDesc());//验证码发送频繁稍后重试
            }
        }else{
            sendSmsVo = new SendSmsVo(phone);
        }

        //生成短信验证码
        Integer code = RandomNum.SIX_NUM.randomNum();
        sendSmsVo.setCode(code);
		ArrayList<String> send = new ArrayList<String>();
		send.add(code.toString());
        //发送短信验证码
        try {
			SmsTxSend.sendSms(phone,send);
		} catch (Exception e) {
			LOGGER.error("sendSmsCode:"+e.getMessage());
		}

        //缓存到redis
        redisService.del(key);
        redisService.setex(key,ApartmentConstant.SMSCODE_CACHE_TIME,sendSmsVo.toString());

        return ResultUtil.generateResult(ResultCodeEnum.OK.getCode(),ResultCodeEnum.OK.getDesc(),code);
    }

    public Result login(LoginParamVo loginParamVo) throws Exception {
    	String phone =  "";
    	System.out.println("login param:"+loginParamVo.toString());
        //判断验证码是否正确
        if(!loginParamVo.isWxMobile() && StringUtil.strIsNullOrEmpty(loginParamVo.getSmscode())){
            return ResultUtil.generateResult(ResultCodeEnum.INVALID_CODE.getCode(),ResultCodeEnum.INVALID_CODE.getDesc());
        }
        else if(!loginParamVo.isWxMobile()&& loginParamVo.getSmscode().equals(code)){
            //判断用户是否存在
            FLockUser user = userService.findByParams(DataUtil.generateMap("phone",phone));
            if(user == null){
                user = new FLockUser(loginParamVo.getPhone()) ;
                jpaService.save(user);
            }else{
                user.setLastLoginTime(DateUtil.nowDateTime());
            }

            TokenVo tokenVo = tokenService.getToken(user.getId().toString());

            user.setToken(tokenVo.getToken());
            jpaService.save(user);

            return ResultUtil.generateResult(ResultCodeEnum.OK.getCode(),ResultCodeEnum.OK.getDesc(),JSON.parseObject(tokenVo.toString()));
        }
        else if(!loginParamVo.isWxMobile()){
        	String key = ApartmentConstant.SEND_SMS_CODE_KEY+loginParamVo.getPhone() ;
        	String smsCodeStr = redisService.get(key);
        	if(StringUtil.strIsNullOrEmpty(smsCodeStr)){
        		return ResultUtil.generateResult(ResultCodeEnum.INVALID_CODE.getCode(),ResultCodeEnum.INVALID_CODE.getDesc());
        	}
        	SendSmsVo sendSmsVo = JSON.parseObject(smsCodeStr,SendSmsVo.class);
        	if(Integer.valueOf(sendSmsVo.getCode()).intValue()!=sendSmsVo.getCode().intValue()){
        		return ResultUtil.generateResult(ResultCodeEnum.INVALID_CODE.getCode(),ResultCodeEnum.INVALID_CODE.getDesc());
        	}
        }
        if(loginParamVo.isWxMobile()) {
        	String result = WechatDecryptDataUtil.decryptData(loginParamVo.getPhone(), loginParamVo.getSessionKey(), loginParamVo.getIv());
        	if(result==null) {
        		 return ResultUtil.generateResult(ResultCodeEnum.INVALID_PARAMS.getCode(),ResultCodeEnum.INVALID_PARAMS.getDesc());
        	}
        	JSONObject json = JSONObject.parseObject(result);
        	if(json.getString("phoneNumber")==null||loginParamVo.getPhone().isEmpty()) {
        		return ResultUtil.generateResult(ResultCodeEnum.ERROR_PHONE.getCode(),ResultCodeEnum.ERROR_PHONE.getDesc(),null);
        	}
        	phone = json.getString("phoneNumber");
        	loginParamVo.setPhone(phone);
        	
        }else {
        	if(loginParamVo.getPhone()==null||loginParamVo.getPhone().isEmpty()) {
        		return ResultUtil.generateResult(ResultCodeEnum.ERROR_PHONE.getCode(),ResultCodeEnum.ERROR_PHONE.getDesc(),null);
        	}
        	phone =loginParamVo.getPhone();
        }
        //判断用户是否存在
        FLockUser user = userService.findByParams(DataUtil.generateMap("phone",phone));
        if(user == null){
            user = new FLockUser(loginParamVo.getPhone()) ;
            jpaService.save(user);
        }else{
            user.setLastLoginTime(DateUtil.nowDateTime());
        }

        TokenVo tokenVo = tokenService.getToken(user.getId().toString());

        user.setToken(tokenVo.getToken());
        jpaService.save(user);

        return ResultUtil.generateResult(ResultCodeEnum.OK.getCode(),ResultCodeEnum.OK.getDesc(),JSON.parseObject(tokenVo.toString()));

    }

    @Override
    public Result refreshToken(String authorization) {
        //重新生成token
        TokenVo tokenVo = tokenService.reshToken(authorization);
        return ResultUtil.generateResult(ResultCodeEnum.OK.getCode(),ResultCodeEnum.OK.getDesc(),JSON.parseObject(tokenVo.toString()));
    }

    @Override
    public Result getOpenId(String code) {
    	JSONObject openId = OpenIdUtil.oauth2GetOpenid(code);
        if(StringUtil.strIsNullOrEmpty(openId)){
            return ResultUtil.generateResult(ResultCodeEnum.DATA_ERROR.getCode(),ResultCodeEnum.DATA_ERROR.getDesc());
        }

        int isExist = 1;
        int expires = 0;
        String token = "";
        FLockUser user = userService.findByParams(DataUtil.generateMap("openId",openId));
        //openid登录，如果系统不存在该openid或者该openid用户未绑定手机号，都要跳转到登录绑定页
        if(user == null || StringUtil.strIsNullOrEmpty(user.getPhone())){
            isExist=0;
        }else{
            TokenVo tokenVo = tokenService.getToken(user.getId().toString());
            user.setToken(tokenVo.getToken());
            jpaService.save(user);

            expires=tokenVo.getExpires();
            token=tokenVo.getToken();
        }
         return ResultUtil.generateResult(ResultCodeEnum.OK.getCode(),ResultCodeEnum.OK.getDesc(),DataUtil.generateMap("openId",openId,"isExist",isExist,"token",token,"expires",expires));
    }


    @Override
    public Result loginBindPhone(Integer type, LoginBindPhoneVo loginBindPhoneVo) {

        //判断验证码是否正确
        String key = ApartmentConstant.SEND_SMS_CODE_KEY+loginBindPhoneVo.getPhone() ;
        String smsCodeStr = redisService.get(key);
        if(StringUtil.strIsNullOrEmpty(smsCodeStr)){
            return ResultUtil.generateResult(ResultCodeEnum.INVALID_CODE.getCode(),ResultCodeEnum.INVALID_CODE.getDesc());
        }
        SendSmsVo sendSmsVo = JSON.parseObject(smsCodeStr,SendSmsVo.class);
        if(Integer.valueOf(sendSmsVo.getCode()).intValue()!=sendSmsVo.getCode().intValue()){
            return ResultUtil.generateResult(ResultCodeEnum.INVALID_CODE.getCode(),ResultCodeEnum.INVALID_CODE.getDesc());
        }

        //判断手机号是否被绑定
        FLockUser user = userService.findByParams(DataUtil.generateMap("phone",loginBindPhoneVo.getPhone()));
        if(user!=null && user.getOpenId()!=null){
            return ResultUtil.generateResult(ResultCodeEnum.PHONE_BINDED.getCode(),ResultCodeEnum.PHONE_BINDED.getDesc());
        }

        //新建用户，生成token
        if(user==null){
            user = new FLockUser(loginBindPhoneVo.getPhone());
        }
        user.setOpenId(loginBindPhoneVo.getOpenId());
        user.setAvatar(loginBindPhoneVo.getAvatarUrl());
        user.setNickName(loginBindPhoneVo.getNickName());
        user.setLastLoginTime(DateUtil.nowDateTime());
        if(user.getId()==null){
            jpaService.save(user);
        }
        TokenVo tokenVo = tokenService.getToken(user.getId().toString());
        user.setToken(tokenVo.getToken());
        jpaService.save(user);

        return ResultUtil.generateResult(ResultCodeEnum.OK.getCode(),ResultCodeEnum.OK.getDesc(),DataUtil.generateMap("token",tokenVo.getToken(),"expires",tokenVo.getExpires()));
    }

	@Override
	public Result updateUserInfo(String authorization, UserInfoVo userInfoVo) {
		// TODO Auto-generated method stub
		return null;
	}
}
